package demo;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author ZhouWeiBo
 * @create 2022/6/7
 */
public class GroupList implements Collection<Employee, Link> {

    private String empId = null;

    /**
     * Key -> ID
     * Value -> 员工信息
     */
    private Map<String, Employee> eMap = new ConcurrentHashMap<>();

    private Map<String, List<Link>> linkMap = new ConcurrentHashMap<>();
    private Map<String, String> invertedMap = new ConcurrentHashMap<>();

    @Override
    public boolean add(Employee e) {
        if (empId == null && eMap.size() == 0) {
            empId = e.getId();
        }
        return null != eMap.put(e.getId(), e);
    }

    @Override
    public boolean remove(Employee e) {
        return null != eMap.remove(e.getId());
    }

    @Override
    public boolean addLink(String empId, Link link) {
        invertedMap.put(link.getToId(), link.getFromId());
        if (linkMap.containsKey(empId)) {
            return linkMap.get(empId).add(link);
        } else {
            List<Link> linkList = new LinkedList<>();
            linkList.add(link);
            linkMap.put(empId, linkList);
        }
        return true;
    }

    @Override
    public boolean removeLink(String key) {
        return null != linkMap.remove(key);
    }

    @Override
    public Iterator<Employee> iterator() {
        return new Iterator<Employee>() {
            final HashMap<String, Integer> keyMap = new HashMap<>();

            int totalIndex = 0;

            private String fromId = empId;

            private String toId = empId;


            @Override
            public boolean hasNext() {
                return totalIndex < eMap.size();
            }

            @Override
            public Employee next() {
                List<Link> links = linkMap.get(toId);
                int cursorIdx = getCursorIdx(toId);

                // 同级节点扫描
                if (null == links) {
                    cursorIdx = getCursorIdx(fromId);
                    links = linkMap.get(fromId);
                }
                // 上级节点扫描
                while (cursorIdx > links.size() - 1) {
                    fromId = invertedMap.get(fromId);
                    cursorIdx = getCursorIdx(fromId);
                    links = linkMap.get(fromId);
                }

                // 获取节点
                Link link = links.get(cursorIdx);

                toId = link.getToId();
                fromId = link.getFromId();

                totalIndex++;
                return eMap.get(toId);
            }

            public int getCursorIdx(String key) {
                int idx = 0;
                if (keyMap.containsKey(key)) {
                    idx = keyMap.get(key);
                    keyMap.put(key, ++idx);
                } else {
                    keyMap.put(key, idx);
                }
                return idx;
            }
        };
    }
}
